Skip to content

Add AlwaysRecordSampler#4823

Open
majanjua-amzn wants to merge 1 commit intoopen-telemetry:mainfrom
majanjua-amzn:always-record-sampler
Open

Add AlwaysRecordSampler#4823
majanjua-amzn wants to merge 1 commit intoopen-telemetry:mainfrom
majanjua-amzn:always-record-sampler

Conversation

@majanjua-amzn
Copy link
Contributor

@majanjua-amzn majanjua-amzn commented Nov 28, 2025

Description

Adds a new AlwaysRecordSampler as per:

This sampler behaves the same as it's root sampler, with the exception that it will replace any DROP decisions with an equivalent RECORD one, while maintaining the attributes and trace state from the decision created by the root sampler.

Also renamed the folder holding the tests for experimental sampling features from composite_sampler to sampling_experimental, as more than just the composite sampler is being tested in this folder, respecting the organization of the files in the src folder.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Unit tests

Does This PR Require a Contrib Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@xrmx
Copy link
Contributor

xrmx commented Nov 28, 2025

We need to wait for the specs to be approved and released before merging this

@xrmx xrmx moved this to Ready for review in @xrmx's Python PR digest Nov 28, 2025
@majanjua-amzn
Copy link
Contributor Author

@xrmx spec is merged, ready for review!

@majanjua-amzn
Copy link
Contributor Author

Hey folks, any update here? @xrmx perhaps?

Also, seems the PR build is failing with something unrelated to my changes, perhaps needs to be rerun

Copy link

@42Questions 42Questions left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had some questions regarding the use of passed attributes vs. result.attributes, and some of the testing.

_root_sampler: Sampler

def __init__(self, root_sampler: Sampler):
if not root_sampler:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not root_sampler:
if root_sampler is None:

This sampler will return the sampling result of the provided `_root_sampler`, unless the
sampling result contains the sampling decision `Decision.DROP`, in which case, a
new sampling result will be returned that is functionally equivalent to the original, except that
it contains the sampling decision `SamplingDecision.RECORD_ONLY`. This ensures that all

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it contains the sampling decision `SamplingDecision.RECORD_ONLY`. This ensures that all
it contains the sampling decision `Decision.RECORD_ONLY`. This ensures that all

Comment on lines +74 to +81
def _wrap_result_with_record_only_result(
result: SamplingResult, attributes: Attributes
) -> SamplingResult:
return SamplingResult(
Decision.RECORD_ONLY,
attributes,
result.trace_state,
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to in-line this since it's only called once, also is it intentional that the result.attributes are not being used?

Suggested change
def _wrap_result_with_record_only_result(
result: SamplingResult, attributes: Attributes
) -> SamplingResult:
return SamplingResult(
Decision.RECORD_ONLY,
attributes,
result.trace_state,
)
def _wrap_result_with_record_only_result(
result: SamplingResult
) -> SamplingResult:
return SamplingResult(
Decision.RECORD_ONLY,
result.attributes,
result.trace_state,
)

self.assertNotEqual(actual_result, root_result)
self.assertEqual(actual_result.decision, expected_decision)

self.assertEqual(actual_result.attributes, root_result.attributes)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the root sampler adds or changes attributes? This also ties into how _wrap_result_with_record_only_result doesn't use result.attributes, is this intentional?

Comment on lines +70 to +71
sampling_trace_state: TraceState = TraceState()
sampling_trace_state.add("key", sampling_decision.name)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add returns a new TraceState,
def add(self, key: str, value: str) -> "TraceState":
...
Returns:
A new TraceState with the modifications applied.
...
"""

so could this be:

Suggested change
sampling_trace_state: TraceState = TraceState()
sampling_trace_state.add("key", sampling_decision.name)
sampling_trace_state = TraceState().add("key", sampling_decision.name)

([#4862](https://github.com/open-telemetry/opentelemetry-python/pull/4862))
- `opentelemetry-exporter-otlp-proto-http`: fix retry logic and error handling for connection failures in trace, metric, and log exporters
([#4709](https://github.com/open-telemetry/opentelemetry-python/pull/4709))
- feat: Add AlwaysRecordSampler

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to align the changelog style

Suggested change
- feat: Add AlwaysRecordSampler
- Add AlwaysRecordSampler

Comment on lines +68 to +71
def get_description(self):
return (
"AlwaysRecordSampler{" + self._root_sampler.get_description() + "}"
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def get_description(self):
return (
"AlwaysRecordSampler{" + self._root_sampler.get_description() + "}"
)
def get_description(self) -> str:
return f"AlwaysRecordSampler{{{self._root_sampler.get_description()}}}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

3 participants